﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace TathamOddie.OpenSearchValidator.Logic.Tasks.Rss
{
	public abstract class XmlValidationTask : IValidationTask
	{
		string resourceName;
		Uri sourceUri;
		string xmlContent;
		string xsdContent;

		public XmlValidationTask(string resourceName, Uri sourceUri, string xmlContent, string xsdContent)
		{
			this.resourceName = resourceName;
			this.sourceUri = sourceUri;
			this.xmlContent = xmlContent;
			this.xsdContent = xsdContent;
		}

		public ValidationTaskResult Validate(ValidationServices services, ValidationState state)
		{
			var result = new ValidationTaskResult();

			var xsdResults = XsdValidator.Validate(xmlContent, xsdContent);

			if (xsdResults.Length > 0)
			{
				result.AddMessage(MessageType.Warning, "Failed while validating {0} from [{1}] against XSD. Errors follow.", resourceName, sourceUri);
				foreach (var xsdResult in xsdResults) result.Messages.Add(xsdResult);
			}
			else
			{
                result.AddMessage(MessageType.Success, "Validated {0} from [{1}] against XSD.", resourceName, sourceUri);
				OnValidateSuccess(result);
			}

            if (xsdResults.Length == 0)
            {
                var document = new XmlDocument();
                document.LoadXml(xmlContent);
                var declaration = document.HasChildNodes
                    ? document.FirstChild as XmlDeclaration
                    : (XmlDeclaration)null;
                if (declaration != null &&
                    !string.IsNullOrEmpty(declaration.Encoding))
                {
                    try
                    {
                        var encoding = Encoding.GetEncoding(declaration.Encoding);
                        if (encoding == Encoding.UTF8)
                        {
                            result.AddMessage(MessageType.Success, "The XML at [{0}] is being correctly served as UTF-8 encoding which will make Internet Explorer happy.", sourceUri);
                        }
                        else
                        {
                            result.AddMessage(MessageType.Failure, "The XML at [{0}] should be served as UTF-8 encoding but is currently being served as [{1}]. Internet Explorer has a rather picky XML parser that fails on encodings like UTF-16 if the user does not have certain language packs installed.", sourceUri, declaration.Encoding);
                        }
                    }
                    catch (ArgumentException)
                    {
                        result.AddMessage(MessageType.Failure, "The XML at [{0}] specifies an unrecognized encoding of [{1}].", sourceUri, declaration.Encoding);
                    }
                }
            }

			return result;
		}

		protected virtual void OnValidateSuccess(ValidationTaskResult result)
		{
		}
	}
}